﻿using SocketTestClient.ConnectionContoller;
using SocketTestClient.RequestObject;
using SocketTestClient.Sender;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SocketTestClient
{
    class Program
    {
        static void Main(string[] args)
        {

            System.Console.WindowWidth = (int)(System.Console.LargestWindowWidth * 0.7);
            System.Console.WindowHeight = (int)(System.Console.LargestWindowHeight * 0.7);
            System.Console.WriteLine("Socket Pipe Started!");

            // TestClientDeamon();
            TestSocketPipe();


        }

        static void TestSocketPipe()
        {
            MultPipeTest test;
            TestRequest testReq = new TestRequest();

            test = new MultPipeTest(new SocketSender(), 5);
            test.Run(testReq);
            test = new MultPipeTest(new SocketSender(), 5);
            test.Run(testReq);
            test = new MultPipeTest(new SocketSender(), 5);
            test.Run(testReq);
            test = new MultPipeTest(new SocketSender(), 5);
            test.Run(testReq);
            test = new MultPipeTest(new SocketSender(), 5);
            test.Run(testReq);


        }


        static void TestClientDeamon()
        {
            ClientControl ctrl = new ClientControl();
            ctrl.StartListen();
        }
    }

    class MultPipeTest
    {
        ISender _sender;
        Thread[] _threads;
        IRequest _requeset;
        int _maxCount = -1;
        int _id;
        public MultPipeTest(ISender sender, int threadCount)
        {
            _sender = sender;
            _threads = new Thread[threadCount];
            _id = 1;

        }

        public void Run(IRequest requeset, int maxCount = -1)
        {
            _requeset = requeset;
            _maxCount = maxCount;
            for (int i=0;i<_threads.Length;i++)
            {
                Thread thr = new Thread(new ThreadStart(SubThreadMain));
                _threads[i] = thr;
                thr.Start();
            }
        }

        private void SubThreadMain()
        {
            int id;

            Thread.BeginCriticalRegion();
            id = _id;
            _id++;
            Thread.EndCriticalRegion();

            SinglePipeTest test = new SinglePipeTest(_sender, id);
            test.Run(_requeset, _maxCount);
        }
    }

    class SinglePipeTest
    {
        ISender _sender;
        int _id;
        ulong _sendCount;
        public SinglePipeTest(ISender sender, int id=0)
        {
            _sender = sender;
            _id = id;
            _sendCount = 1;
        }
        public void Run(IRequest requeset, int maxCount = -1)
        {
            Random rand = new Random();
            IRequest req = requeset;
            int count = maxCount;
            while (true)
            {
                if(count == 0)
                {
                    break;
                }
                else if(count > 0)
                {
                    count--;
                }

                int ret = _sender.Send(req);
                if (ret < 0)
                {
                    System.Console.WriteLine("[" + _id + "]" + "Wait Connection.");
                    Thread.Sleep(1000);
                }
                else
                {
                    System.Console.WriteLine("[" + _id + "]" + "Send Packet: " + _sendCount++);
                    Thread.Sleep(rand.Next(100));
                }

            }
        }

    }
}
